package strategy;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector;

import main.U;
import main.Util;
import mt.BaiduMT;
import mt.C2EMT;
import mt.GoogleMT;
import mt.YoudaoMT;

public class Strategy {
	/**
	 * 这个方法被BestStrategy继承，表明具体的组合方式。
	 * @param f
	 * @return
	 * @throws Exception
	 */
     double getTranslationScore(TranslatinData f) throws Exception {
    	 return -1;
     }
	
	
	/**
	 * 从三家结果中选择最好的一句
	 * 
	 * 它来调用getTranslationScore，决定如何组合各组特征的打分。
	 * 
	 * @param translationResults  对于一句话的翻译结果，{google=xxx, baidu=xxx, youdao=xxx}
	 * @return 最好的一家结果
	 * @throws Exception
	 */
	public String selectAnswer(HashMap<String, String> translationResults) throws Exception{

		//get features
		double bestScore =-Integer.MAX_VALUE;
		String bestTranslationSource=null;// GoogleMT.label, BaiduMT.label, or YoudaoMT.label
		
		//获得每一家提供的结果的属性，每一家的这一句对应一个TranslationData
		HashMap<String, TranslatinData> TranslatinDatas = 
			TranslatinData.getTranslationDatas(translationResults);
		
		for(String source: TranslatinDatas.keySet()){
			//决定如何使用各组特征的得分！
			double score = getTranslationScore(TranslatinDatas.get(source));
			if(score>bestScore){
				bestScore=score;
				bestTranslationSource =source;
			}
		}
		return TranslatinDatas.get(bestTranslationSource).translation;
		
	}

	public String selectAnswerWithRef(HashMap<String, String> translationResults, ArrayList<String> refList) throws Exception{
		//get features
		double bestScore =-Integer.MAX_VALUE;
		String bestTranslationSource=null;
		
		//获得每一家提供的结果的属性，每一家的这一句对应一个TranslationData
		HashMap<String, TranslatinData> TranslatinDatas = 
			TranslatinData.getTranslationDatasWithRef(translationResults, refList);
		
		for(String source: TranslatinDatas.keySet()){
			//决定如何使用各组特征的得分！
			double score = getTranslationScore(TranslatinDatas.get(source));
			if(score>bestScore){
				bestScore=score;
				bestTranslationSource =source;
			}	
		}
		return TranslatinDatas.get(bestTranslationSource).translation;
	}
	
	public HashMap<Integer, ArrayList<String>> getUpperBoundRefs() throws Exception {
		
		HashMap<Integer, ArrayList<String>> refMap = new HashMap<Integer, ArrayList<String>>();
		Vector<String> vRefs = U.file2vector("data/evaData/ref");
		for( int i = 1; i <= 1664; i++) {
			ArrayList<String> refs = new ArrayList<String>();
			for (String s : vRefs) {
				if (s.startsWith("<seg id=\"" + i + "\">")) {
					refs.add(s.replaceAll("<.*?>", ""));
					//System.out.println(s.replaceAll("<.*?>", ""));
				}
			}
			refMap.put(i, refs);
		}
		System.out.println("refMap.size()=" + refMap.size());
		return refMap;
	}
	
	
	
	
	/**
	 *    Evaluate
	 *    
	 * @throws Exception
	 */
	public void evaluate() throws Exception{
		
		HashMap<Integer, ArrayList<String>> refMap = getUpperBoundRefs();
		
		//make result from 3 result log
		Vector<String> vBaidu = U.file2vector("./data/mtRes/baidu.txt");
		Vector<String> vGoogle = U.file2vector("./data/mtRes/google.txt");
		Vector<String> vYoudao = U.file2vector("./data/mtRes/youdao.txt");
		U.Assert(vBaidu.size()==vGoogle.size() && vYoudao.size()==vGoogle.size());
		
		int googleCount =0;
		int baiduCount =0;
		int youdaoCount =0;
		int sentenceLength=0;
		
		System.out.println("translations loading and selection step:");
		
		//res存放最终结果
		Vector<String> res = new Vector<String>();
		for(int i=0; i<vBaidu.size();i++){
			//对每一句话，获得三家的翻译结果。
			//mtTranslationRes = {google=xxx, baidu=xxx, youdao=xxx}
			HashMap<String, String> mtTranslationRes =new HashMap<String, String>();
			mtTranslationRes.put(GoogleMT.label, vGoogle.get(i));
			mtTranslationRes.put(BaiduMT.label, vBaidu.get(i));
			mtTranslationRes.put(YoudaoMT.label, vYoudao.get(i));

			//选一家最好的结果，它来调用getTranslationScore，决定如何组合各组特征的打分。
			String result = selectAnswer(mtTranslationRes);
			//String result = selectAnswerWithRef(mtTranslationRes, refMap.get(i + 1));
			
			if(result.equals(mtTranslationRes.get(BaiduMT.label))) baiduCount++;
			if(result.equals(mtTranslationRes.get(GoogleMT.label))) googleCount++;
			if(result.equals(mtTranslationRes.get(YoudaoMT.label))) youdaoCount++;
			
			sentenceLength+= Util.getSentenceLength(result);
			res.add(result);
			
			//if(i%100 ==0)
			//	System.out.print(i+" ");
		}
		
		double bleu =fromVectorToBleu(res);
		

		System.out.println("\n\n");
		System.err.println("Evaluation Result");
		System.err.println("===========================");
		System.err.println("Bleu score\t"+ bleu);
		System.err.println("Sentence average length\t"+ (double)sentenceLength/res.size());
		
		int sum = baiduCount+googleCount+youdaoCount;
		System.err.println("Baidu\t"+ (double)baiduCount/sum);
		System.err.println("Youdao\t"+ (double)youdaoCount/sum);
		System.err.println("Google\t"+ (double)googleCount/sum);
	}

	//helper
	public static  double fromVectorToBleu(Vector<String> res) throws Exception {

		String tmpFilePath ="./toBeEva.txt";
		
		//log.txt用来记录eval.bat运行的结果。
		String logPath ="./data/evaData/log.txt";
		
		//vector -> file
		U.vector2file(res,tmpFilePath);
		
		//file -> 转换成eval.perl使用的XML格式
		C2EMT.toTst(tmpFilePath, "./data/evaData/tst");
		new File(tmpFilePath).delete();
		System.err.println();
		System.err.println("Executing perl program, please wait!");
		U.executeCommandLine("eval.bat");
		String fileString =U.file2str(logPath);
		
		//log is generated!
		String begin = "BLEU score =";
		String end ="   BLEU-SBP";
		int beginIndex =fileString.indexOf(begin)+begin.length();
		int endIndex =fileString.indexOf(end);
		//new File("./data/evaData/tst").delete();
		new File(logPath).delete();
		return Double.parseDouble(fileString.substring(beginIndex,endIndex));
	}

	
	
	
	
	
	
	/**
	 * 测试一句话使用的testStrategy。   输出三家的各项属性的得分。
	 * 
	 * @param chinese
	 * @throws Exception
	 */
	public void testStrategy(String chinese) throws Exception{
		HashMap<String, TranslatinData> featureScore = TranslatinData.getTranslationDatas(chinese);
		
		System.out.println("source: "+chinese+"\n");
		System.out.println();System.out.println();
		for(String source : featureScore.keySet()){
			
			TranslatinData f =featureScore.get(source);
			System.out.println(source);
			System.out.println("------");
			System.out.println(f.translation);
			System.out.println("ppl:\t" + f.lmLogP);
			System.out.println("editDistance:\t" + f.editDistance);
			System.out.println("BLEU:\t" + f.BLEU);
			System.out.println("METEOR:\t" + f.METEOR);
			System.out.println();
		}
		
	}
	
	/**
	 * 测试一句话使用的translate。输出三家中的最好结果。
	 * 
	 * @param chinese
	 * @return
	 * @throws Exception
	 */
	// translation is from selection of 3 MT's translations
	public String translate(String chinese) throws Exception{

		//get features
		double bestScore =-Integer.MAX_VALUE;
		String bestTranslationSource=null;
		
		HashMap<String, TranslatinData> TranslatinDatas = TranslatinData.getTranslationDatas(chinese);
		for(String source: TranslatinDatas.keySet()){
			double score = getTranslationScore(TranslatinDatas.get(source));
			if(score>bestScore){
				bestScore=score;
				bestTranslationSource =source;
			}	
		}
		return TranslatinDatas.get(bestTranslationSource).translation;
	}

	public static void main(String args[]) throws Exception{
		new Strategy().getUpperBoundRefs();
	}
}
